<template>
  <div :class="isAdmin ? 'admT' : 'admF'">
    <div id="map" style="width: 100%; height: 100%"></div>
    <div class="funBox">
      <div class="funBox_btn" @click="changePlay">
        <img src="@/assets/images/play.png" alt="" v-if="!isPlay" />
        <img src="@/assets/images/suspend.png" alt="" v-else />
      </div>
      <div class="funLine">
        <el-slider @input="changeSchedule" v-model="schedule" :step="1" :min="0" :max="list.length" show-stops
          ref="slider" :show-tooltip="false" v-if="isFlag">
        </el-slider>
      </div>
      <div>
        <el-dropdown @command="handleCommand">
          <div style="color: #ffffff">速度 {{ speed }}</div>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item :command="2000">1</el-dropdown-item>
              <el-dropdown-item :command="1500">2</el-dropdown-item>
              <el-dropdown-item :command="1000">3</el-dropdown-item>
              <el-dropdown-item :command="500">4</el-dropdown-item>
              <el-dropdown-item :command="200">5</el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
      </div>
    </div>
    <!-- <historyTrackPlayback :Popup="PopupRight"></historyTrackPlayback> -->
    <div class="customTips" v-if="schedule" :style="{ left: tipLeft }">
      {{ formatTooltip }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted, watch } from 'vue';
import { useRoute } from 'vue-router';
import { useStore } from 'vuex';
import { shipHistory } from "@/api/map/map";
import historyTrackPlayback from "@/views/historyTrackPlayback";

// 声明全局类型
declare const window: Window & { 
  T: any;
};

// 接口定义
interface ShipPoint {
  lon: number;
  lat: number;
  time: number;
  cog: number;
  sog?: number;
  heading?: number;
}

// 设置响应式数据
const route = useRoute();
const store = useStore();
const isAdmin = ref(true);
const map = ref<any>(null);
const isPlay = ref(true); // 播放状态
const list = ref<ShipPoint[]>([]);
const ship = ref<HTMLElement | null>(null); // 船marker
const nowLng = ref<number | null>(null);
const nowlat = ref<number | null>(null);
const speed = ref(1); // 速度
const timers = ref<number[]>([]); // 延时器
const schedule = ref(0); // 进度
const isSwitch = ref(true); // 开关
const interval = ref(2000);
const sliderVal = ref(0);
const tipLeft = ref('0');
const id = ref<string | null>(null);
const hyimgurl = ref<string | null>(null);
const isFlag = ref(false);
const onHJlist = ref<ShipPoint[]>([]);
const dateVal = ref<number | null>(null);
const lay = ref<any>(null);

// 计算属性
const formatTooltip = computed(() => {
  if (schedule.value) {
    return new Date(list.value[schedule.value - 1].time * 1000).toLocaleString();
  }
  return '';
});

// 监听
watch(() => schedule.value, (val) => {
  const sliderElement = document.getElementsByClassName("el-slider__button-wrapper")[0];
  if (sliderElement) {
    const div = sliderElement.getBoundingClientRect();
    tipLeft.value = parseInt(div.left.toString()) + "px";
  }
});

// 方法定义
// 设置地图
const setMap = () => {
  hyimgurl.value = window.hyimgurl;
  const tLayer = new window.T.TileLayer(hyimgurl.value, { minZoom: 5, maxZoom: 18 });
  lay.value = { layers: [tLayer] };
  map.value = new window.T.Map("map", lay.value);
  
  const lnglat = new window.T.LngLat(121.79152, 29.983);
  map.value.centerAndZoom(lnglat, 15);

  map.value.addEventListener("zoomend", () => {
    if (ship.value) {
      // 地图缩放更新船的位置
      const latlng = new window.T.LngLat(nowLng.value, nowlat.value);
      const pos = map.value.lngLatToLayerPoint(latlng);
      ship.value.style.top = pos.y - 15 + "px";
      ship.value.style.left = pos.x - 10 + "px";

      map.value.clearOverLays();
      renew();
    }
  });

  if (id.value) {
    getShipHistory();
  }
};

// 船舶历史航迹
const getShipHistory = () => {
  shipHistory({
    hours: 48,
    shipId: id.value,
  }).then((res) => {
    if (res.code == 200) {
      list.value = [];
      const data = res.data;
      for (let i = 0; i < data.length; i++) {
        if (data[i]) {
          for (let j = 0; j < data[i].length; j++) {
            const val = JSON.parse(data[i][j]);
            list.value.push(val);
          }
        }
      }
      map.value.panTo(new window.T.LngLat(list.value[0].lon, list.value[0].lat));
      dateVal.value = parseInt((list.value.length / (48 * 20)).toString()) > 1
        ? parseInt((list.value.length / (48 * 20)).toString())
        : 1;
      isFlag.value = true;
    }
  });
};

// 切换播放状态
const changePlay = () => {
  isPlay.value = !isPlay.value;
  if (isPlay.value) {
    changeSchedule();
  }
};

// 改变进度
const changeSchedule = () => {
  if (isPlay.value && schedule.value < list.value.length) {
    const timer = setTimeout(() => {
      setLocusPlayData(schedule.value);
    }, interval.value);
    timers.value.push(timer);
  }
};

// 准备航迹
const setLocusPlayData = (scheduleVal: number) => {
  isSwitch.value = false;
  
  if (ship.value && ship.value.parentNode) {
    // 如果marker图标存在，先清除
    const parent = ship.value.parentNode;
    parent.removeChild(ship.value);
  }
  
  nowLng.value = list.value[scheduleVal].lon;
  nowlat.value = list.value[scheduleVal].lat; // 保留一下当前marker坐标
  
  // 设置marker图标
  const img = document.createElement("img");
  img.src = require("@/assets/images/icon1.png");
  const latlng = new window.T.LngLat(list.value[scheduleVal].lon, list.value[scheduleVal].lat);
  ship.value = document.createElement("div");
  img.style.width = "10px";
  img.style.height = "20px";
  img.style.transform = `rotate(${list.value[scheduleVal].cog}deg)`;
  ship.value.appendChild(img);
  ship.value.style.position = "absolute";
  map.value.getPanes().overlayPane.appendChild(ship.value);
  const pos = map.value.lngLatToLayerPoint(latlng);
  ship.value.style.top = pos.y - 15 + "px";
  ship.value.style.left = pos.x - 10 + "px";

  // 当前坐标和上一个坐标比较，没有变化或者变化不大不新增label标志
  if (scheduleVal != 0) {
    const preLat = list.value[scheduleVal - 1].lat.toFixed(2);
    const preLng = list.value[scheduleVal - 1].lon.toFixed(2);
    
    if (preLat == list.value[scheduleVal].lat.toFixed(2) && preLng == list.value[scheduleVal].lon.toFixed(2)) {
      const origin = new window.T.LngLat(list.value[scheduleVal - 1].lon, list.value[scheduleVal - 1].lat);
      const terminalPoint = new window.T.LngLat(list.value[scheduleVal].lon, list.value[scheduleVal].lat);
      const points = [origin, terminalPoint];
      const line = new window.T.Polyline(points, {
        color: "red",
        weight: 2,
        opacity: 0.5,
      });
      map.value.addOverLay(line);
    } else {
      // 从第二个点位开始，轨迹连线
      const origin = new window.T.LngLat(list.value[scheduleVal - 1].lon, list.value[scheduleVal - 1].lat);
      const terminalPoint = new window.T.LngLat(list.value[scheduleVal].lon, list.value[scheduleVal].lat);
      const points = [origin, terminalPoint];
      const line = new window.T.Polyline(points, {
        color: "red",
        weight: 2,
        opacity: 0.5,
      });
      map.value.addOverLay(line);

      // 设置时间标志
      let lng, lat;
      lng = (list.value[scheduleVal].lon + list.value[scheduleVal].lon * 0.99995) / 2;
      lat = (list.value[scheduleVal].lat + list.value[scheduleVal].lat * 1.00007) / 2;
      
      const label = new window.T.Label({
        text: new Date(list.value[scheduleVal].time * 1000).toLocaleString(),
        position: new window.T.LngLat(lng, lat),
      });
      label.setOpacity(0.7);
      label.setBackgroundColor("rgba(255,255,255,0.3)");

      // 创建地图文本对象
      map.value.addOverLay(label);
      
      // label连线
      const termPoint = label.getLngLat();
      const Tpoints = [latlng, termPoint];
      const tline = new window.T.Polyline(Tpoints, {
        color: "#333333",
        weight: 2,
      });

      // 点是基于label的左上角，根据情况设置label偏移对应左上角/右下角
      if (scheduleVal % 2 == 0) {
        label.setOffset(new window.T.Point(-120, -10));
      } else {
        label.setOffset(new window.T.Point(-15, 10));
      }
      map.value.addOverLay(tline);
    }
  } else {
    // 设置时间标志
    let lng, lat;
    if (scheduleVal % 2 == 0) {
      lng = (list.value[scheduleVal].lon + list.value[scheduleVal].lon * 0.99995) / 2;
      lat = (list.value[scheduleVal].lat + list.value[scheduleVal].lat * 1.00007) / 2;
    } else {
      lng = (list.value[scheduleVal].lon + list.value[scheduleVal].lon * 1.00005) / 2;
      lat = (list.value[scheduleVal].lat + list.value[scheduleVal].lat * 0.99995) / 2;
    }

    const label = new window.T.Label({
      text: new Date(list.value[scheduleVal].time * 1000).toLocaleString(),
      position: new window.T.LngLat(lng, lat),
    });
    label.setOpacity(0.7);
    label.setBackgroundColor("rgba(255,255,255,0.3)");

    // 创建地图文本对象
    map.value.addOverLay(label);

    // label连线
    const termPoint = label.getLngLat();
    const Tpoints = [latlng, termPoint];
    const tline = new window.T.Polyline(Tpoints, {
      color: "#333333",
      weight: 2,
    });

    // 点是基于label的左上角，根据情况设置label偏移对应左上角/右下角
    if (scheduleVal % 2 == 0) {
      label.setOffset(new window.T.Point(-120, -10));
    } else {
      label.setOffset(new window.T.Point(-15, 10));
    }
    map.value.addOverLay(tline);
  }

  isSwitch.value = true;
  schedule.value += 1;
  onHJlist.value.push(list.value[scheduleVal]);
};

// 缩放后更新
const renew = () => {
  for (let i = 0; i < onHJlist.value.length; i++) {
    const latlng = new window.T.LngLat(onHJlist.value[i].lon, onHJlist.value[i].lat);
    
    if (i != 0) {
      const preLat = onHJlist.value[i - 1].lat.toFixed(2);
      const preLng = onHJlist.value[i - 1].lon.toFixed(2);
      
      if (preLat == onHJlist.value[i].lat.toFixed(2) && preLng == onHJlist.value[i].lon.toFixed(2)) {
        // 从第二个点位开始，轨迹连线
        const origin = new window.T.LngLat(onHJlist.value[i - 1].lon, onHJlist.value[i - 1].lat);
        const terminalPoint = new window.T.LngLat(onHJlist.value[i].lon, onHJlist.value[i].lat);
        const points = [origin, terminalPoint];
        const line = new window.T.Polyline(points, {
          color: "red",
          weight: 2,
          opacity: 0.5,
        });
        map.value.addOverLay(line);
      } else {
        // 从第二个点位开始，轨迹连线
        const origin = new window.T.LngLat(onHJlist.value[i - 1].lon, onHJlist.value[i - 1].lat);
        const terminalPoint = new window.T.LngLat(onHJlist.value[i].lon, onHJlist.value[i].lat);
        const points = [origin, terminalPoint];
        const line = new window.T.Polyline(points, {
          color: "red",
          weight: 2,
          opacity: 0.5,
        });
        map.value.addOverLay(line);

        // 设置时间标志
        const lng = (onHJlist.value[i].lon + onHJlist.value[i].lon * 0.99995) / 2;
        const lat = (onHJlist.value[i].lat + onHJlist.value[i].lat * 1.00007) / 2;
        
        const label = new window.T.Label({
          text: new Date(onHJlist.value[i].time * 1000).toLocaleString(),
          position: new window.T.LngLat(lng, lat),
        });
        label.setOpacity(0.7);
        label.setBackgroundColor("rgba(255,255,255,0.3)");

        // 创建地图文本对象
        map.value.addOverLay(label);
        
        // label连线
        const termPoint = label.getLngLat();
        const Tpoints = [latlng, termPoint];
        const tline = new window.T.Polyline(Tpoints, {
          color: "#333333",
          weight: 2,
        });

        // 点是基于label的左上角，根据情况设置label偏移对应左上角/右下角
        if (i % 2 == 0) {
          label.setOffset(new window.T.Point(-120, -10));
        } else {
          label.setOffset(new window.T.Point(-15, 10));
        }
        map.value.addOverLay(tline);
      }
    } else {
      // 设置时间标志
      const lng = (onHJlist.value[i].lon + onHJlist.value[i].lon * 0.99995) / 2;
      const lat = (onHJlist.value[i].lat + onHJlist.value[i].lat * 1.00007) / 2;

      const label = new window.T.Label({
        text: new Date(onHJlist.value[i].time * 1000).toLocaleString(),
        position: new window.T.LngLat(lng, lat),
      });
      label.setOpacity(0.7);
      label.setBackgroundColor("rgba(255,255,255,0.3)");

      // 创建地图文本对象
      map.value.addOverLay(label);

      // label连线
      const termPoint = label.getLngLat();
      const Tpoints = [latlng, termPoint];
      const tline = new window.T.Polyline(Tpoints, {
        color: "#333333",
        weight: 2,
      });

      // 点是基于label的左上角，根据情况设置label偏移对应左上角/右下角
      if (i % 2 == 0) {
        label.setOffset(new window.T.Point(-120, -10));
      } else {
        label.setOffset(new window.T.Point(-15, 10));
      }
      map.value.addOverLay(tline);
    }
  }
};

// 切换速度
const handleCommand = (num: number) => {
  interval.value = num;
};

// 生命周期钩子
onMounted(() => {
  if (route.query.count) {
    id.value = route.query.count as string;
  }
  
  const roles = store.getters.roles;
  isAdmin.value = roles.indexOf("admin") >= 0;
  
  setMap();
});
</script>

<style scoped>
.admT {
  width: 100%;
  height: calc(100vh - 50px);
  position: relative;
}

.admF {
  width: 100%;
  height: 100vh;
  position: relative;
}

.funBox {
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  min-width: 600px;
  height: 70px;
  display: flex;
  align-items: center;
  background-color: rgba(31, 63, 130, 0.8);
  color: white;
  box-shadow: 0 0 7px 1px rgba(0, 0, 0, 0.55);
  z-index: 1000;
  padding: 0 20px;
}

.funBox_btn>img {
  width: 30px;
  height: 30px;
}

.funBox_btn:hover {
  cursor: pointer;
}

.funLine {
  width: 500px;
  margin: 0 20px;
}

.customTips {
  height: 30px;
  padding: 0 10px;
  color: #ffffff;
  font-size: 14px;
  position: fixed;
  bottom: 40px;
  z-index: 1000;
  background: rgba(0, 0, 0, 0.5);
  border-radius: 6px;
  display: flex;
  justify-content: center;
  align-items: center;
}

::v-deep .el-slider__runway {
  background-color: #464547;
}

::v-deep .el-slider__stop {
  background: #d3d7d4;
}
</style>
